﻿using Domain.Entity;
using DtoFw;
using DtoFw.Query;
using Repository;
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using Util;
using System.Net.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using DtoFw.Enum;
using Cache;
using Serilog;
using DtoFw.Result;
using SqlSugar;
using System.Security.Cryptography;
using System.IO;

namespace Service
{
    public class PartyService
    {
        private readonly RoomAreaRepository _roomAreaRepository;
        private readonly WarnCheckoutRepository _warnCheckoutRepository;
        private readonly CaseRepository _caseRepository;
        private readonly MainOrganRepository _mainOrganRepository;
        private readonly CasePhysicalEvidenceRepository _casePhysicalEvidenceRepository;
        private readonly CasePhysicalEvidenceTransfereRepository _casePhysicalEvidenceTransfereRepository;

        public PartyService(RoomAreaRepository roomAreaRepository, WarnCheckoutRepository warnCheckoutRepository, CaseRepository caseRepository,
            MainOrganRepository mainOrganRepository, CasePhysicalEvidenceRepository casePhysicalEvidenceRepository, CasePhysicalEvidenceTransfereRepository casePhysicalEvidenceTransfereRepository)
        {
            this._roomAreaRepository = roomAreaRepository;
            this._warnCheckoutRepository = warnCheckoutRepository;
            this._caseRepository = caseRepository;
            this._mainOrganRepository = mainOrganRepository;
            this._casePhysicalEvidenceRepository = casePhysicalEvidenceRepository;
            this._casePhysicalEvidenceTransfereRepository = casePhysicalEvidenceTransfereRepository;
        }


        /// <summary>
        /// 查询区域
        /// </summary>
        /// <returns></returns>
        public BaseGenericResult<List<AreaQueryDto>> QueryAreas(long organId)
        {
            var list = _roomAreaRepository.Query(new BaseQuery() { }, x => x.Where(x => x.OrganId == organId))?.OrderBy(v => v.OrderBy)
                 .ToList();
            var dtoList = AutoMapperExtension.MapTo<RoomAreaEntity, AreaQueryDto>(list);
            return BaseGenericResult<List<AreaQueryDto>>.Succeed(dtoList);
        }


        /// <summary>
        /// 查询区域
        /// </summary>
        /// <returns></returns>
        public BaseGenericResult<EvidenceToAreaDto> GetEvidenceByEviNo(string eveidenceNo, long organId)
        {
            var dtoList = _roomAreaRepository.GetEvidenceByEviNo(eveidenceNo, organId);
            if (dtoList != null)
            {
                if (dtoList.Status == "0")
                {

                    dtoList.Status = "已登记";
                }
                else if (dtoList.Status == "1")
                {
                    dtoList.Status = "已入库";
                }
                else
                {
                    dtoList.Status = "已出库";
                }
            }

            return BaseGenericResult<EvidenceToAreaDto>.Succeed(dtoList);
        }

        /// <summary>
        /// 查询区域
        /// </summary>
        /// <returns></returns>
        public BaseGenericResult<Pager<WarnCheckoutDto>> GetWarnCheckout(string eveidenceNo, long organId, int page, int pageSize)
        {

            Pager<WarnCheckoutEntity> list = _warnCheckoutRepository.GetPager(
                new BaseQuery() { Page = page, PageSize = pageSize },
                x => x.WhereIF(!string.IsNullOrEmpty(eveidenceNo), v => v.EvidenceNo == eveidenceNo)
                //.Where(x => x.OrganId == organId)
                );

            var dtoList = AutoMapperExtension.MapTo<WarnCheckoutEntity, WarnCheckoutDto>(list.Data);

            Pager<WarnCheckoutDto> pager = new Pager<WarnCheckoutDto>();
            pager.Data = dtoList;
            pager.TotalCount = list.TotalCount;

            return BaseGenericResult<Pager<WarnCheckoutDto>>.Succeed(pager);
        }


        /// <summary>
        /// 物品朔源查询
        /// </summary>
        /// <param name="eveidenceNo"></param>
        /// <param name="organId"></param>
        /// <returns></returns>
        public BaseGenericResult<SourceEviDto> GetSource(string eveidenceNo, long organId)
        {

            //查询案件
            SourceEviDto dto = _caseRepository.GetCaseEntityByEviNo(eveidenceNo, organId);
            if (dto != null)
            {
                MainOrganEntity organEntity = _mainOrganRepository.Query(new BaseQuery() { }, x => x.Where(v => v.Id == organId)).Single();

                dto.Data.Add(new SourceDto { Title = "案件信息", Time = dto.CaseTime, V1 = dto.HostUserOrganName, V2 = dto.HostUserName, V3 = dto.InspectionNo, V4 = dto.CaseNo });
                dto.Data.Add(new SourceDto { Title = "登记", Time = dto.CreateTime, V1 = organEntity.Name, V2 = dto.Creator, V3 = dto.InspectionNo, V4 = dto.CaseNo });


                List<CasePhysicalEvidenceTransfereEntity> transListEntity = _caseRepository.GetTansByEviNo(eveidenceNo, organId);
                foreach (var item in transListEntity)
                {
                    if (item.DeliveryDicType == 6)
                    {
                        //回库
                        dto.Data.Add(new SourceDto { Title = "回库", Time = item.CreateTime, V1 = item.Location, V2 = item.Transferor, V3 = item.Receiver });


                    }
                    else if (item.DeliveryDicType == 8)
                    {
                        //入库
                        dto.Data.Add(new SourceDto { Title = "入库", Time = item.CreateTime, V1 = item.Location, V2 = item.Transferor, V3 = item.Receiver });
                    }
                    else if (item.DeliveryDicType == 7)
                    {
                        //更换位置
                        dto.Data.Add(new SourceDto { Title = "位置转移", Time = item.CreateTime, V1 = item.Remark, V2 = item.Location, V3 = item.Creator });
                    }
                    else
                    {
                        //其他出库
                        dto.Data.Add(new SourceDto { Title = item.DeliveryDicTypeName, Time = item.CreateTime, V1 = item.ReceiverOrgan, V2 = item.Receiver, V3 = item.Transferor });
                    }

                }

            }

            return BaseGenericResult<SourceEviDto>.Succeed(dto);
        }


        /// <summary>
        /// Rfid报警
        /// </summary>
        /// <param name="dto"></param>
        public BaseGenericResult<bool> GetRfid(RfidDto dto)
        {
            Log.Information(JsonConvert.SerializeObject(dto));
            if (dto != null && dto.@params.opResultItems != null && dto.@params.opResultItems.Length != 0)
            {
                var isWran = false;
                foreach (var item in dto.@params.opResultItems)
                {
                    var linq = _casePhysicalEvidenceRepository.Query(new BaseQuery() { }, x => x.Where(v => v.RFID == item.epc));
                    if (linq.Any())
                    {
                        CasePhysicalEvidenceEntity entity = linq.Single();

                        var caseLinq = _caseRepository.Query(new BaseQuery() { }, x => x.Where(v => v.Id == entity.CaseId));


                        if (entity.Status == (int)EnumEvidenceStatus.RK && caseLinq.Any())
                        {
                            var caseEntity = caseLinq.Single();
                            _warnCheckoutRepository.Insert(new WarnCheckoutEntity
                            {
                                CaseId = caseEntity.Id,
                                CaseName = caseEntity.CaseName,
                                CaseNo = caseEntity.CaseNo,
                                InvNo = caseEntity.InspectionNo,
                                EvidenceId = entity.Id,
                                EvidenceName = entity.Name,
                                EvidenceNo = entity.No,
                                IsResolved = 0,
                                CreateTime = DateTime.Now,
                                RFID = item.epc,
                                IsDeleted = false

                            });

                            isWran = true;
                        }
                    }

                    if (isWran)
                    {
                        Post(new { deviceId = dto.@params.deviceId }, GlobalData.EvidenceInfo.RfidWran);
                    }

                    return BaseGenericResult<bool>.Succeed(true);
                }
            }

            return BaseGenericResult<bool>.Succeed(false);
        }


        /// <summary>
        /// Rfid读取
        /// </summary>
        /// <param name="evidenceId"></param>
        /// <returns></returns>
        public BaseGenericResult<bool> ReaderRfidInfo(List<RfidReaderDto> dto)
        {
            //ReaderRfidDto
            //老牛在物品详情页 面物品后面放一个RFID绑定按钮  调用 http://127.0.0.1:8080/rfidreader/readepc  get请求 ，会返回  ReaderRfidDto 结构给你 你把里面的epc 物品ID传给我 来做保存
            bool result = false;

            //string json = Get(" http://127.0.0.1:8080/rfidreader/readepc");
            //if (!string.IsNullOrEmpty(json))
            {
                //ReaderRfidDto dto = JsonConvert.DeserializeObject<ReaderRfidDto>(json);
                //if (dto != null && dto.success)
                foreach (var item in dto)
                {
                    //写入数据库
                    var linq = _casePhysicalEvidenceRepository.Query(new BaseQuery() { Id = item.evidenceId });
                    if (linq.Any())
                    {
                        CasePhysicalEvidenceEntity entity = linq.First();
                        entity.RFID = item.epc;

                        if (_casePhysicalEvidenceRepository.Save(entity)?.Id > 0)
                        {
                            result = true;
                        }
                    }

                }
            }

            return BaseGenericResult<bool>.Succeed(result);
        }

        /// <summary>
        /// 盘点
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public BaseGenericResult<TaskInfoDto> RfidTask(BaseQuery dto)
        {
            var linq = _casePhysicalEvidenceRepository.Query(dto).ToList();
            TaskInfoDto task = new TaskInfoDto();

            Random rd = new Random();
            task.taskId = rd.Next(100000, 999999);
            task.taskName = task.taskId.ToString();
            task.type = 0;
            foreach (var item in linq)
            {
                task.taskData.Add(new Taskdata { evidenceName = item.Name, epc = item.RFID, registerState = 1, address = item.ExtractionOrganName });
            }
            return BaseGenericResult<TaskInfoDto>.Succeed(task);
        }

        /// <summary>
        /// 读卡
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public BaseGenericResult<string> Readepc()
        {
            return BaseGenericResult<string>.Succeed(Get(GlobalData.EvidenceInfo.Readepc));
        }

        /// <summary>
        /// 盘点
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public BaseGenericResult<string> Taskdown(HaiKangPanDianDto dto)
        {
            return BaseGenericResult<string>.Succeed(Post(dto, GlobalData.EvidenceInfo.Taskdown));
        }

        /// <summary>
        /// Rfid打印
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public BaseGenericResult<string> Propertyprint(HaiKangPrintDto dto)
        {
            return BaseGenericResult<string>.Succeed(Post(dto, GlobalData.EvidenceInfo.Propertyprint));
        }

        /// <summary>
        /// 海康获取要开门的数据
        /// </summary>
        /// <param name="tranNo"></param>
        /// <returns></returns>
        public HaiKangTransDto QueryTransEvidences(string tranNo)
        {
            return _casePhysicalEvidenceTransfereRepository.GetTransfereEvidences(tranNo);
        }

        /// <summary>
        /// 获得用户数据
        /// </summary>
        /// <param name="corpCode"></param>
        /// <param name="deviceCode"></param>
        /// <param name="startTime"></param>
        /// <param name="endTime"></param>
        /// <param name="orderby"></param>
        /// <param name="pageNum"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public HaiKangBoxUserList GetBoxUserList(string corpCode, string deviceCode, string startTime, string endTime, string orderby, int pageNum, int pageSize)
        {
            List<UserList> boxList = _casePhysicalEvidenceTransfereRepository.GetBoxUserList(corpCode, deviceCode, startTime, endTime, orderby, pageNum, pageSize);
            foreach (var item in boxList)
            {
                if (!string.IsNullOrWhiteSpace(item.password))
                    item.password = Encrypt(item.password);
                if (!string.IsNullOrWhiteSpace(item.cellCode))
                {
                    try
                    {
                        List<Cell2DeviceCode> list = JsonConvert.DeserializeObject<List<Cell2DeviceCode>>(item.cellCode);
                        var c2Code = list.FirstOrDefault(v => v.deviceCode == deviceCode);
                        if (c2Code != null)
                        {
                            item.cellCode = c2Code.cellCodes;
                            continue;
                        }

                        item.cellCode = string.Empty;
                    }
                    catch (Exception)
                    {
                        item.cellCode = string.Empty;
                    }
                }
            }
            HaiKangBoxUserList users = new HaiKangBoxUserList();
            users.data = boxList;
            users.total = _casePhysicalEvidenceTransfereRepository.GetBoxUserListCount(startTime, endTime);
            return users;
        }

        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="plainText"></param>
        /// <returns></returns>
        public string Encrypt(string plainText)
        {
            byte[] strKey = { 5, 7, 8, 9, 0, 2, 1, 6 }, strParam = { 6, 9, 8, 5, 1, 6, 2, 8 };
            byte[] inputBytes = Encoding.UTF8.GetBytes(plainText);
            using (var des = DES.Create())
            {
                using (var ms = new MemoryStream())
                {
                    using (var cs = new CryptoStream(ms, des.CreateEncryptor(strKey, strParam), CryptoStreamMode.Write))
                    {
                        cs.Write(inputBytes, 0, inputBytes.Length);
                        cs.FlushFinalBlock();
                        return Convert.ToBase64String(ms.ToArray());
                    }
                }
            }
        }

        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="cipherText">解密的文本</param>
        /// <returns></returns>
        public string Decrypt(string cipherText)
        {
            byte[] strKey = { 5, 7, 8, 9, 0, 2, 1, 6 }, strParam = { 6, 9, 8, 5, 1, 6, 2, 8 };
            byte[] inputBytes = Convert.FromBase64String(cipherText);
            using (var des = DES.Create())
            {
                using (var ms = new MemoryStream())
                {
                    using (var cs = new CryptoStream(ms, des.CreateDecryptor(strKey, strParam), CryptoStreamMode.Write))
                    {
                        cs.Write(inputBytes, 0, inputBytes.Length);
                        cs.FlushFinalBlock();
                        return Encoding.UTF8.GetString(ms.ToArray());
                    }
                }
            }
        }


        /// <summary>
        /// Post请求
        /// </summary>
        /// <param name="o"></param>
        /// <param name="url"></param>
        /// <returns></returns>
        private string Post(object o, string url)
        {
            using (var client = new HttpClient())
            {

                try
                {

                    //var str = JsonConvert.SerializeObject(o);
                    string str = JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings
                    {
                        Converters = { new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" } }
                    });
                    HttpContent content = new StringContent(str);
                    content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
                    HttpResponseMessage response = client.PostAsync(url, content).Result;//改成自己的
                    response.EnsureSuccessStatusCode();//用来抛异常的
                    string responseBody = response.Content.ReadAsStringAsync().Result;

                    return responseBody;
                }
                catch (Exception e)
                {
                }

                return "{\"success\": false, \"errorCode\": 500, \"message\": \"软件服务未开启\" }";
            }

        }

        /// <summary>
        /// get请求
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        private string Get(string url)
        {
            using (HttpClient client = new HttpClient())
            {
                try
                {
                    HttpResponseMessage response = client.GetAsync(url).Result;
                    response.EnsureSuccessStatusCode();//用来抛异常的
                    string responseBody = response.Content.ReadAsStringAsync().Result;

                    return responseBody;
                }
                catch (Exception e)
                {
                }

                return "{\"success\": false, \"errorCode\": 500, \"message\": \"软件服务未开启\" }";
            }

        }
    }
}
